#pragma once
#include "gp_Pnt.h"
#include "gp_Dir.h"


class gp_Pnt;
class gp_Dir;
class gp_Ax2;
class gp_Trsf;
class gp_Vec;


//! Describes an axis in 3D space. <br>
//! An axis is defined by: <br>
//! -   its origin (also referred to as its "Location point"), and <br>
//! -   its unit vector (referred to as its "Direction" or "main   Direction"). <br>
//! An axis is used: <br>
//! -   to describe 3D geometric entities (for example, the <br>
//! axis of a revolution entity). It serves the same purpose <br>
//! as the STEP function "axis placement one axis", or <br>
//! -   to define geometric transformations (axis of <br>
//!   symmetry, axis of rotation, and so on). <br>
//! For example, this entity can be used to locate a geometric entity <br>
//!  or to define a symmetry axis. <br>
class gp_Ax1  {

public:
  //! Creates an axis object representing Z axis of <br>
//!            the reference co-ordinate system. <br>
      gp_Ax1();
  
//!  P is the location point and V is the direction of <me>. <br>
      gp_Ax1(const gp_Pnt& P,const gp_Dir& V);
  //! Assigns V as the "Direction"  of this axis. <br>
        void SetDirection(const gp_Dir& V) ;
  //! Assigns  P as the origin of this axis. <br>
        void SetLocation(const gp_Pnt& P) ;
  //! Returns the direction of <me>. <br>
       const gp_Dir& Direction() const;
  //! Returns the location point of <me>. <br>
       const gp_Pnt& Location() const;
  
//!  Returns True if  : <br>
//!  . the angle between <me> and <Other> is lower or equal <br>
//!    to <AngularTolerance> and <br>
//!  . the distance between <me>.Location() and <Other> is lower <br>
//!    or equal to <LinearTolerance> and <br>
//!  . the distance between <Other>.Location() and <me> is lower <br>
//!    or equal to LinearTolerance. <br>
       bool IsCoaxial(const gp_Ax1& Other,const double AngularTolerance,const double LinearTolerance) const;
  
//!  Returns True if the direction of the <me> and <Other> <br>
//!  are normal to each other. <br>
//! That is, if the angle between the two axes is equal to Pi/2. <br>
//! Note: the tolerance criterion is given by AngularTolerance.. <br>
        bool IsNormal(const gp_Ax1& Other,const double AngularTolerance) const;
  
//!  Returns True if the direction of <me> and <Other> are <br>
//!  parallel with opposite orientation. That is, if the angle <br>
//! between the two axes is equal to Pi. <br>
//! Note: the tolerance criterion is given by AngularTolerance. <br>
        bool IsOpposite(const gp_Ax1& Other,const double AngularTolerance) const;
  
//!  Returns True if the direction of <me> and <Other> are <br>
//!  parallel with same orientation or opposite orientation. That <br>
//! is, if the angle between the two axes is equal to 0 or Pi. <br>
//! Note: the tolerance criterion is given by <br>
//! AngularTolerance. <br>
        bool IsParallel(const gp_Ax1& Other,const double AngularTolerance) const;
  
//!  Computes the angular value, in radians, between <me>.Direction() and <br>
//!  <Other>.Direction(). Returns the angle between 0 and 2*PI <br>
//!  radians. <br>
        double Angle(const gp_Ax1& Other) const;
  //!  Reverses the unit vector of this axis. <br>
//! and  assigns the result to this axis. <br>
        void Reverse() ;
  //! Reverses the unit vector of this axis and creates a new one. <br>
        gp_Ax1 Reversed() const;
  
//!  Performs the symmetrical transformation of an axis <br>
//!  placement with respect to the point P which is the <br>
//!  center of the symmetry and assigns the result to this axis. <br>
       void Mirror(const gp_Pnt& P) ;
  //! Performs the symmetrical transformation of an axis <br>
//!  placement with respect to the point P which is the <br>
//!  center of the symmetry and creates a new axis. <br>
       gp_Ax1 Mirrored(const gp_Pnt& P) const;
  
//!  Performs the symmetrical transformation of an axis <br>
//!  placement with respect to an axis placement which <br>
//!  is the axis of the symmetry and assigns the result to this axis. <br>
       void Mirror(const gp_Ax1& A1) ;
  
//!  Performs the symmetrical transformation of an axis <br>
//!  placement with respect to an axis placement which <br>
//!  is the axis of the symmetry and creates a new axis. <br>
       gp_Ax1 Mirrored(const gp_Ax1& A1) const;
  
//!  Performs the symmetrical transformation of an axis <br>
//!  placement with respect to a plane. The axis placement <br>
//!  <A2> locates the plane of the symmetry : <br>
//!  (Location, XDirection, YDirection) and assigns the result to this axis. <br>
       void Mirror(const gp_Ax2& A2) ;
  
//!  Performs the symmetrical transformation of an axis <br>
//!  placement with respect to a plane. The axis placement <br>
//!  <A2> locates the plane of the symmetry : <br>
//!  (Location, XDirection, YDirection) and creates a new axis. <br>
       gp_Ax1 Mirrored(const gp_Ax2& A2) const;
  //! Rotates this axis at an angle Ang (in radians) about the axis A1 <br>
//! and assigns the result to this axis. <br>
        void Rotate(const gp_Ax1& A1,const double Ang) ;
  //! Rotates this axis at an angle Ang (in radians) about the axis A1 <br>
//! and creates a new one. <br>
        gp_Ax1 Rotated(const gp_Ax1& A1,const double Ang) const;
  
//! Applies a scaling transformation to this axis with: <br>
//! -   scale factor S, and <br>
//! -   center P and assigns the result to this axis. <br>
        void Scale(const gp_Pnt& P,const double S) ;
  
//! Applies a scaling transformation to this axis with: <br>
//! -   scale factor S, and <br>
//! -   center P and creates a new axis. <br>
        gp_Ax1 Scaled(const gp_Pnt& P,const double S) const;
  //! Applies the transformation T to this axis. <br>
//! and assigns the result to this axis. <br>
        void Transform(const gp_Trsf& T) ;
  
//! Applies the transformation T to this axis and creates a new one. <br>
//!  Translates an axis plaxement in the direction of the vector <br>
//!  <V>. The magnitude of the translation is the vector's magnitude. <br>
        gp_Ax1 Transformed(const gp_Trsf& T) const;
  
//! Translates this axis by the vector V, <br>
//! and assigns the result to this axis. <br>
        void Translate(const gp_Vec& V) ;
  
//! Translates this axis by the vector V, <br>
//! and creates a new one. <br>
        gp_Ax1 Translated(const gp_Vec& V) const;
  
//! Translates this axis by: <br>
//! the vector (P1, P2) defined from point P1 to point P2. <br>
//! and assigns the result to this axis. <br>
        void Translate(const gp_Pnt& P1,const gp_Pnt& P2) ;
  
//! Translates this axis by: <br>
//! the vector (P1, P2) defined from point P1 to point P2. <br>
//! and creates a new one. <br>
        gp_Ax1 Translated(const gp_Pnt& P1,const gp_Pnt& P2) const;
    const gp_Pnt& _CSFDB_Getgp_Ax1loc() const { return loc; }
    const gp_Dir& _CSFDB_Getgp_Ax1vdir() const { return vdir; }

private: 
	gp_Pnt loc;
	gp_Dir vdir;
};


